#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include "SDL_rwops.h"
#include "luaopen.h"

typedef struct _LISTINFO {
	char path[256];
	Uint32 hash;
	Uint32 offset;
	Uint32 len;
}LISTINFO;

LISTINFO* scriptlist;
Uint32 scriptnum = 0;
SDL_RWops* rw;

int LUA_LoadScriptPack(lua_State* L)
{
	if (scriptnum!=0 || lua_getfield(L, LUA_REGISTRYINDEX, "ggepack") != LUA_TSTRING)
		return 0;
	size_t size;
	const void* pack = (void*)lua_tolstring(L, -1, &size);
	rw = SDL_RWFromConstMem(pack, (int)size);
	int head;
	if (SDL_RWread(rw, &head, sizeof(int), 1) == 0 || head != 0x50454747)//GGEP
		return 0;
	if (SDL_RWread(rw, &scriptnum, sizeof(Uint32), 1) == 0 || SDL_RWseek(rw, 4, RW_SEEK_CUR) == -1)
		return 0;

	scriptlist = (LISTINFO*)SDL_malloc(scriptnum* sizeof(LISTINFO));
	if (SDL_RWread(rw, scriptlist, sizeof(LISTINFO), scriptnum) == 0) {
		scriptnum = 0;
		return 0;
	}
		
	return 0;
}

int LUA_GetScriptData(lua_State* L)
{
	const char* file = luaL_checkstring(L, 1);
	Uint32 hash = g_tohash(file);
	if (scriptnum>0)
	{
		for (Uint32 i = 0; i < scriptnum; i++)
		{
			if (scriptlist[i].hash == hash)
			{
				if (SDL_RWseek(rw, scriptlist[i].offset, RW_SEEK_SET) == -1)
					return 0;
				luaL_Buffer b;
				char* ptr = luaL_buffinitsize(L, &b, scriptlist[i].len);
				if (SDL_RWread(rw, ptr, scriptlist[i].len, 1) != 0) {
					luaL_pushresultsize(&b, scriptlist[i].len);
					return 1;
				}else
					return 0;
			}
		}
	}
	return 0;
}

int LUA_GetScriptList(lua_State* L)
{
	lua_createtable(L, scriptnum, 0);
	for (Uint32 i = 0; i < scriptnum; i++)
	{
		lua_pushstring(L, scriptlist[i].path);
		lua_seti(L, -2, i + 1);
	}
	return 1;
}

int LUA_FreeScript(lua_State* L)
{
	if (scriptnum)
		SDL_free(scriptlist);
	scriptnum = 0;
	return 0;
}
